/*
 * Wevo2 - Distributed Evolutionary Computation Library.
 * Copyright (C) 2009 Marcin Brodziak
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
 *    Boston, MA  02110-1301  USA
 */
package engine.operators.binary;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import engine.Operator;
import engine.Population;
import engine.individuals.ProgramedTrafficNetIndividual;
import engine.individuals.TrafficNetIndividual;

/**
 * Uniform crossover operator. Offsprings have equal probability
 * of inheriting gene from both of his parents.
 * 
 */
public class UniformCrossover implements Operator<ProgramedTrafficNetIndividual> {

  /**
   * Creates a uniform crossover object.
   */
  public UniformCrossover() {
  }

  /** {@inheritDoc} */
  public Population<ProgramedTrafficNetIndividual> apply(
      Population<ProgramedTrafficNetIndividual> population) {
    Iterator<ProgramedTrafficNetIndividual> iterator = population.getIndividuals().iterator();
    List<ProgramedTrafficNetIndividual> output = new LinkedList<ProgramedTrafficNetIndividual>();

    while (iterator.hasNext()) {
    	ProgramedTrafficNetIndividual b1 = iterator.next();
    	if (iterator.hasNext()) {
    		ProgramedTrafficNetIndividual b2 = iterator.next();

    		TrafficNetIndividual[] crossedOver = b1.crossOver(b2);

				output.add((ProgramedTrafficNetIndividual) crossedOver[0]);
				output.add((ProgramedTrafficNetIndividual) crossedOver[1]);
    	} else {
    		output.add(b1);
    	}
    }

    return new Population<ProgramedTrafficNetIndividual>(output);
  }
}
